package com.project.util.qrcode;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.project.common.Constants;
import com.project.util.OSSUtil;

public class QrcodeUtil {
	
    public static void  main(String [] args) throws IOException{  
//      生成二维码  
    	QrcodeUtil.createCode(500,500,"http://blog.csdn.net/gao36951","D:" + File.separator + "qrcode.png");  
//      解析二维码  
    	QrcodeUtil.parseCode(new File("D:/qrcode.png"));  
          
    }
    
    /**
     * 生成本地二维码
     * 
     * @param width
     * @param height
     * @param content
     * @param filename
     *            文件名称(文件不存在，重新生成新的)
     * @return
     */
    public static String createLocalQrcode(int width, int height, String content, String filename) {
        String path = Constants.FILE_PATH_TEMP + "/qrcode";
        String ossUrl = "qrcode/" + filename + ".jpg";
        String outPath = path + "/" + filename + ".jpg";
        File pathFile = new File(path);
        if (!pathFile.exists() && !pathFile.isDirectory()) {
            pathFile.mkdirs();
        }
        // 生成二维码
        QrcodeUtil.createCode(width, height, content, outPath);
        // 上传到oss
        OSSClient ossClient = OSSUtil.getOSSClient();
        try {
            ossClient.putObject(OSSUtil.IMAGE_BUCKETNAME, ossUrl, new FileInputStream(outPath));
        } catch (OSSException | ClientException | FileNotFoundException e1) {
            e1.printStackTrace();
        }
        ossClient.shutdown();
        return ossUrl;
    }

	/**
	 * 二维码的生成   
	 * @param width 宽度
	 * @param height 高度
	 * @param content 内容
	 * @param outputPath 输出路径
	 */
    public static void createCode(int width, int height, String content, String outputPath){  
    	//生成的图片格式
    	String format = "png";
    	/** 
         * 设置二维码的参数 
         */  
        HashMap hints = new HashMap();  
        // 内容所使用编码  
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");  
        // 容错级别
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        try {  
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content,BarcodeFormat.QR_CODE,width,height,hints);  
            // 生成二维码  
            File outputFile = new File(outputPath);  
            MatrixToImageWriter.writeToFile(bitMatrix, format, outputFile);  
              
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
          
    }  
    /** 
     * 二维码的解析 
     * 
     * @param file 
     */  
    public static void parseCode(File file)  
    {  
        try  
        {  
            MultiFormatReader formatReader = new MultiFormatReader();  
   
            if (!file.exists())  
            {  
                return;  
            }  
   
            BufferedImage image = ImageIO.read(file);  
   
            LuminanceSource source = new BufferedImageLuminanceSource(image);  
            Binarizer binarizer = new HybridBinarizer(source);  
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);  
   
            Map hints = new HashMap();  
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");  
   
            Result result = formatReader.decode(binaryBitmap, hints);  
   
            System.out.println("解析结果 = " + result.toString());  
            System.out.println("二维码格式类型 = " + result.getBarcodeFormat());  
            System.out.println("二维码文本内容 = " + result.getText());  
        }  
        catch (Exception e)  
        {  
            e.printStackTrace();  
        }  
    } 
	
}
class MatrixToImageWriter {  
	   
	   private static final int BLACK = 0xFF000000;  
	   private static final int WHITE = 0xFFFFFFFF;  
	   
	   private MatrixToImageWriter() {}  
	   
	     
	   public static BufferedImage toBufferedImage(BitMatrix matrix) {  
	     int width = matrix.getWidth();  
	     int height = matrix.getHeight();  
	     BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
	     for (int x = 0; x < width; x++) {  
	       for (int y = 0; y < height; y++) {  
	         image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);  
	       }  
	     }  
	     return image;  
	   }  
	   
	     
	   public static void writeToFile(BitMatrix matrix, String format, File file)  
	       throws IOException {  
	     BufferedImage image = toBufferedImage(matrix);  
	     if (!ImageIO.write(image, format, file)) {  
	       throw new IOException("Could not write an image of format " + format + " to " + file);  
	     }  
	   }  
	   
	     
	   public static void writeToStream(BitMatrix matrix, String format, OutputStream stream)  
	       throws IOException {  
	     BufferedImage image = toBufferedImage(matrix);  
	     if (!ImageIO.write(image, format, stream)) {  
	       throw new IOException("Could not write an image of format " + format);  
	     }  
	   }  
	   
	 }  
